﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://www.codeplex.com/EmlenMud
using System;
using System.Text;
using System.Linq;
using System.Globalization;
using System.Collections.Generic;

namespace BrainTechLLC
{
    public enum DefaultValue
    {
        None = 0,
        True = 1,
        False = 2
    }

    public static class MiscExtensionMethods
    {
#if SILVERLIGHT
        public static string[] Split(this string orig, char[] delims, int max, StringSplitOptions options)
        {
            string[] strings = orig.Split(delims, options);
            if (strings.Length > max)
            {
                string[] results = new string[max];
                int n = 0;
                for (; n < max - 1; n++)
                {
                    results[n] = strings[n];
                }
                StringBuilder sb = new StringBuilder();
                for (; n < strings.Length - 1; n++)
                {
                    sb.Append(strings[n] + delims[0]);
                }
                sb.Append(strings[n]);
                results[max - 1] = sb.ToString();
                return results;
            }
            else
            {
                return strings;
            }
        }
#endif

        public static bool StripNextWord(this string delimiters, ref string s, out string stringOut)
        {
            if (string.IsNullOrEmpty(s))
            {
                stringOut = null;
                return false;
            }

            string[] strings = s.Split(delimiters.ToCharArray(), 2, StringSplitOptions.RemoveEmptyEntries);

            if (strings.Length == 0)
            {
                s = string.Empty;
                stringOut = null;
                return false;
            }

            if (strings.Length == 1)
            {
                s = string.Empty;
            }
            else
            {
                s = strings[1];
            }
            stringOut = strings[0];
            return true;
        }

        public static string EmptyIfNull(this string s)
        {
            if (string.IsNullOrEmpty(s))
                return string.Empty;

            return s;
        }
        public static bool AreEqual(this object o1, object o2)
        {
            if (o1 == null && o2 == null)
                return true;

            if ((o1 == null && o2 != null) || (o1 != null && o2 == null))
                return false;

            return o1.Equals(o2);
        }

        public static double CreateNumeric(this string value)
        {
            double result;

            if (double.TryParse(
                value,
                NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint |
                NumberStyles.AllowLeadingSign | NumberStyles.AllowLeadingWhite |
                NumberStyles.AllowThousands | NumberStyles.AllowTrailingWhite,
                null,
                out result))
            {
                return result;
            }

            if (value.EndsWith("."))
            {
                if (double.TryParse(
                value.Substring(0, value.Length - 1),
                NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint |
                NumberStyles.AllowLeadingSign | NumberStyles.AllowLeadingWhite |
                NumberStyles.AllowThousands | NumberStyles.AllowTrailingWhite,
                null,
                out result))
                {
                    return result;
                }
            }

            return double.NegativeInfinity;
        }

        public static bool ReturnBoolean(this object o, DefaultValue defaultValue)
        {
            if (o == null)
                return (defaultValue == DefaultValue.True);

            return Convert.ToBoolean(o);
        }

        public static bool AddNonDuplicateLine(this StringBuilder sb, string line)
        {
            if (sb.ToString().IndexOf(line) < 0)
            {
                sb.AppendLine(line);
                return true;
            }

            return false;
        }

        public static bool StartsWith(this string item, params string[] setToCheck)
        {
            foreach (string check in setToCheck)
            {
                if (item.StartsWith(check))
                    return true;
            }

            return false;
        }

        public static bool IsIn<T>(this T item, params T[] setToCheck)
        {
            foreach (T check in setToCheck)
            {
                if (item.Equals(check))
                    return true;
            }

            return false;
        }

        public static T2 TryGetValueOrNull<T1, T2>(this Dictionary<T1, T2> dictionary, T1 key) where T2 : class
        {
            T2 element;

            if (dictionary.TryGetValue(key, out element))
                return element;

            return null;
        }

        public static T2 CheckNull<T1, T2>(this T1 value, T2 valueIfNull, Func<T1, T2> valueIfNotNull) where T1 : class
        {
            if (value == null)
                return valueIfNull;

            return valueIfNotNull(value);
        }

        public static void ForEachIndexed<T>(this List<T> list, Action<int, T> action)
        {
            for (int n = 0; n < list.Count; n++)
                action(n, list[n]);
        }

        public static int Sum<T>(this IEnumerable<T> collection, Func<T, int> returnSum)
        {
            int sum = 0;
            foreach (T item in collection)
            {
                sum += returnSum(item);
            }
            return sum;
        }

        //public static void CopyPropertiesTo(this object o1, object o2)
        //{
        //    Type newType = o2.GetType();

        //    var propertiesToCopy = from pi in o1.GetType().GetProperties()
        //                           let propInfo = newType.GetProperty(pi.Name)
        //                           where propInfo != null && propInfo.CanWrite
        //                           select new { sourcePropInfo = pi, destPropInfo = propInfo };

        //    propertiesToCopy.ForEach((v) =>
        //    {
        //        object val = v.sourcePropInfo.GetValue(o1, null);
        //        try
        //        {
        //            v.destPropInfo.SetValue(o2, val, null);
        //        }
        //        catch (Exception ex) { Debug.WriteLine(ex.ToString()); }
        //    });
        //}
    }
}